package com.huazhicloud.learn;

import com.google.protobuf.Descriptors;
import com.nettylearn.protobuf.*;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 华智云系统
 *
 * @module: TODO
 * @description:TODO
 * @author: wangxu
 * @createDate: 2019/9/25 14:36
 * @version: 1.0
 */
@Slf4j
public class WSServerHandler extends SimpleChannelInboundHandler<BaseRequestProto.BaseRequest> {
    AtomicInteger count=new AtomicInteger(0);
    /**
     * 取消绑定
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        // 可能出现业务判断离线后再次触发 channelInactive
        log.warn("触发 channelInactive 掉线![{}]", ctx.channel().id());
        userOffLine(ctx);
    }

    /**
     * 心跳检查
     *
     * @param ctx
     * @param evt
     * @throws Exception
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        System.out.println("触发了用户事件1" + evt);
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
            // 读空闲
            if (idleStateEvent.state() == IdleState.READER_IDLE) {
                // 关闭用户的连接
                userOffLine(ctx);
            }
        }
        super.userEventTriggered(ctx, evt);
    }

    /**
     * 用户下线
     */
    private void userOffLine(ChannelHandlerContext ctx) throws IOException {
        System.out.println("用戶下线了");
        WSSocketHolder.remove(ctx.channel());
        ctx.channel().close();
    }

    /**
     * 读到客户端的内容 （这里只做心跳检查）
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, BaseRequestProto.BaseRequest msg) throws Exception {
        System.out.println("服务端读取消息");
        System.out.println(msg.getType().getNumber());
        if(msg.getType()== RequestTypeEnumProto.RequestTypeEnum.VISITOR_LOGIN){
            System.out.println("获取到访客登录信息");
            System.out.println(count.incrementAndGet());
            System.out.println(msg.getVisitorLogin().getVisitorCode());
//            System.out.println(msg.getVisitorLogin().getServerid());
            System.out.println(msg.getVisitorLogin().getIsRelogin());
            System.out.println(msg.getCustomerLogin().getIsRelogin());
            System.out.println(msg.getCustomerLogin().getServerid());
            System.out.println(msg.getCustomerLogin().getVisitorCode());

        }else if(msg.getType()== RequestTypeEnumProto.RequestTypeEnum.CUSTOMER_LOGIN){
            System.out.println("获取到用户登录信息");
        }else if(msg.getType()== RequestTypeEnumProto.RequestTypeEnum.HEART_BEAT){
            System.out.println("获取到心跳信息");
        }
        SessionProto.Session.LastMessage lastMessage=SessionProto.Session.LastMessage.newBuilder().setMessageType("001").setFrom("游客").setTo("客服").setBody("{\"name\":\"你好\"}").build();
        SessionProto.Session session=SessionProto.Session.newBuilder().setId("001").setLastMessage(lastMessage).build();
        BaseResponseProto.BaseResponse baseResponse=    BaseResponseProto.BaseResponse.newBuilder().setType(ResponseTypeEnumProto.ResponseTypeEnum.SESSIONS).setSession(session).build();
        ctx.writeAndFlush(baseResponse);
//        switch (type) {
//            case WSReqTypeConstant.LOGIN: // 登录类型
//                log.info("用户登录");
//                userLogin(ctx, uid, sid);
//                break;
//            case WSReqTypeConstant.PING: // 心跳
//                log.info("客户端心跳");
//                break;
//            default:
//                log.info("未知类型");
//        }
    }

    private void userLogin(ChannelHandlerContext ctx, Long uid, String sid) throws IOException {
//        if (!UserLoginUtils.checkToken(uid, sid)) {
//            log.info("非法登录: {}, {}", uid, sid);
//            // 登录异常, 发送下线通知
//            WSBaseResProtoOuterClass.WSBaseResProto wsBaseResProto = WSBaseResProtoOuterClass.WSBaseResProto.newBuilder()
//                    .setType(WSResTypeConstant.LOGIN_OUT)
//                    .setCreateTime(new Date().toString())
//                    .build();
//            // 发送下线消息
//            ctx.writeAndFlush(wsBaseResProto);
//            return;
//        }

        // 判断是否在线, 如果在线, 则剔除当前在线用户
        Channel channel = WSSocketHolder.get(uid);
        // 如果不是第一次登陆, 并且 客户端ID和当前的不匹配, 则通知之前的客户端下线
//        if (channel != null && !ctx.channel().id().equals(channel.id())) {
//            WSBaseResProtoOuterClass.WSBaseResProto wsBaseResProto = WSBaseResProtoOuterClass.WSBaseResProto.newBuilder()
//                    .setType(WSResTypeConstant.WS_OUT)
//                    .setCreateTime(new Date().toString())
//                    .build();
//            // 发送下线消息
//            channel.writeAndFlush(wsBaseResProto);
//        }else{
//            WSMessageResProtoOuterClass.WSMessageResProto wsMessageResProto=WSMessageResProtoOuterClass.WSMessageResProto.newBuilder().setMsgType(0).setMsgContent("服务器推送的消息，你好......").build();
//            WSBaseResProtoOuterClass.WSBaseResProto wsBaseResProto = WSBaseResProtoOuterClass.WSBaseResProto.newBuilder()
//                    .setType(WSResTypeConstant.FRIEND)
//                    .setCreateTime(new Date().toString())
//                    .setMessage(wsMessageResProto)
//                    .build();
//            // 发送下线消息
//            ctx.writeAndFlush(wsBaseResProto);
//        }

        // 加入 在线 map 中
        WSSocketHolder.put(uid, ctx.channel());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        if ("Connection reset by peer".equals(cause.getMessage())) {
            log.error("连接出现问题");
            return;
        }
        log.error(cause.getMessage(), cause);
    }

    public static void main(String args[]){
//        WSBaseResProtoOuterClass.WSBaseResProto wsBaseResProto = WSBaseResProtoOuterClass.WSBaseResProto.newBuilder()
//                .setType(WSResTypeConstant.WS_OUT)
//                .setCreateTime(new Date().toString())
//                .build();
//        CustomerLoginOuterClass.CustomerLogin customerLogin= CustomerLoginOuterClass.CustomerLogin.newBuilder().setCustomerId("1").build();
//        RequestCmdOuterClass.RequestCmd.newBuilder().setType(RequestCmdOuterClass.RequestCmd.RequestType.CUSTOMER_LOGIN).setCustomerLogin(customerLogin).build();
    }
}